package com.guli.mall.serviceBase.globalException;

import com.guli.common.pojo.vo.StatusCodeEnum;
import com.guli.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.BindingException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

/*
 * @Author 罗
 * @date 2020/9/12 - 6:39 下午
 */
@ControllerAdvice
@Slf4j
@ConditionalOnClass(ControllerAdvice.class)
public class GlobalExceptionHandler {

    /**
     * 全局异常
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public R globalExceptionHandler(Exception e) {
        log.error(StatusCodeEnum.GLOBAL_EXCEPTION + "，" + e.getMessage());
        e.printStackTrace();
        return R.error(StatusCodeEnum.GLOBAL_EXCEPTION).put("data", e.getMessage());
    }

    /**
     * 谷粒运行时异常
     */
    @ExceptionHandler(MallException.class)
    @ResponseBody
    public R guliMallExceptionHandler(MallException e) {

        /**
         * 如果异常中指定列枚举，就直接返回枚举中的异常信息
         * */
        /*if (!ObjectUtils.isEmpty(e.getStatusCodeEnum())) {
            e.printStackTrace();
            return R.error(e.getStatusCodeEnum()).put("data",e.getStatusCodeEnum().getMsg());
        }*/

        /**
         * 查看用户在创建异常的时候有没有指定 Message，如果指定了 Message，就使用指定的Message响应到浏览器，否则就使用默认的
         * */
        String errMessage = ObjectUtils.isEmpty(e.getMessage()) ? StatusCodeEnum.GULI_MALL_EXCEPTION.getMsg() : e.getMessage();

        e.printStackTrace();

        /**
         * 查看用户是否抛出异常的时候还抛出了异常代码，如果指定了异常代码，就使用用户指定的，如果没有指定，就使用枚举默认的错误代码
         * */
        Integer errCode = ObjectUtils.isEmpty(e.getCode()) ? StatusCodeEnum.GULI_MALL_EXCEPTION.getCode() : e.getCode();

        log.error("错误代码：" + errCode + "错误消息" + errMessage);

        return R.error(errCode, errMessage).put("data", e.getMessage());
    }

    /**
     * JSR 303 校验异常处理器
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public R bindingExceptionHandler(MethodArgumentNotValidException e) {
        log.error(StatusCodeEnum.VALID_EXCEPTION + "，" + e.getMessage());

        R err = R.error(StatusCodeEnum.VALID_EXCEPTION);

        Map<String, String> map = new HashMap<>();

        for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {
            map.put(fieldError.getField(), fieldError.getDefaultMessage());
        }

        return err.put("data", map);

    }
}
